<template>
  <div
    class="x-textarea-wrap"
    :class="{ 'error': showError, focused: focused }"
  >
    <input
      v-if="placeholder && !text"
      :placeholder="placeholder"
      class="placeholder"
      readonly
    />
    <div
      :ref="setRef"
      class="x-textarea scroll"
      contenteditable="true"
      @input="input"
      @focus="onFocus"
      @blur="onBlur"
    >
      <br />
    </div>
  </div>
</template>
<script
  lang="ts"
  setup
  name="XTextarea"
>
import { equ } from '../../../../package-env';

const props = defineProps({
  value: {
    type: String,
    default: '',
  },
  minRows: {
    type: Number,
    default: equ === 'pc' ? 4 : 2,
  },
  maxRows: {
    type: Number,
    default: 6,
  },
  fontSize: {
    type: Number,
    default: 12,
  },
  lineHeight: {
    type: Number,
    default: 17,
  },
  safeTop: {
    type: Number,
    default: 10,
  },
  safeBottom: {
    type: Number,
    default: 10,
  },
  paddingLeft: {
    type: Number,
    default: 0,
  },
  placeholder: {
    type: String,
    default: '请输入内容',
  },
  error: {
    type: Boolean,
    default: null,
  }
})

const emits = defineEmits(['update:value'])

const el = ref(null)
const text = ref('')
const focused = ref(false);

const showError = computed(() => {
  if (text.value !== '') {
    return false;
  }
  if (props.error && text.value === '') {
    return true;
  }
  if (typeof props.error === 'boolean') {
    return props.error;
  }
});

const onFocus = () => {
  focused.value = true;
};

const onBlur = () => {
  focused.value = false;
}

const setRef = (ref: LooseObject) => {
  el.value = ref
}
const input = () => {
  text.value = `${el.value.innerText || ''}`.replaceAll('\n', '')
  emits('update:value', text.value)
}
const bind = (value: number) => {
  if (equ === 'h5' && !Number.isNaN(+value) || (Number.isNaN(+value) && !`${value}`.endsWith('px'))) {
    const v = parseFloat(`${value}`);
    return `${(v / 375) * 100}vw`;
  }
  return `${value}px`;
}

const cssSizeMap = computed(() => {
  const { minRows, maxRows, lineHeight, safeTop, safeBottom, fontSize } = props;
  const minHeight = minRows * lineHeight + safeTop + safeBottom;
  const maxHeight = maxRows * lineHeight + safeTop + safeBottom;
  const map = {
    // fontSize: bind(fontSize),
    lineHeight: bind(lineHeight),
    minHeight: bind(minHeight),
    maxHeight: bind(maxHeight),
  };
  return map;
});

onMounted(() => {
  text.value = props.value
  el.value.innerText = props.value
})
</script>

<style lang="scss">
.x-textarea-wrap {
  position: relative;
  flex: 1;
  font-size: $form-font-size;
  width: calc(100% - 5em - 7.5px);
  min-height: v-bind('cssSizeMap.minHeight');
}

.x-textarea,
input.placeholder {
  // font-size: v-bind('cssSizeMap.fontSize');
  line-height: v-bind('cssSizeMap.lineHeight');
  padding: 9px 10px;
}

.x-textarea {
  @apply relative z-20 overflow-x-hidden break-words;
  margin-left: auto;
  margin-right: auto;
  outline: none;
  min-height: v-bind('cssSizeMap.minHeight');
  max-height: v-bind('cssSizeMap.maxHeight');
  width: 100%;
  background: $input-bg;
  border-radius: 6px;
  color: $input-color;
}

input.placeholder {
  @include form-placeholder;
  position: absolute;
  border: none;
  outline: none;
  background: transparent;
  padding-left: 10px;
  pointer-events: none;
  z-index: 111;
}

.error {
  box-shadow: $form-error;
}
</style>
